home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / sound / sbf3.zip / DMA_CODE.ASM < prev    next >
Assembly Source File  |  1993-09-18  |  16KB  |  411 lines

  1. ; DMA_CODE.ASM
  2.  
  3.                 IDEAL
  4.                 Model large
  5.  
  6. ;+---------------------------------------------------------------------------+
  7. ;|  IBM-PC(tm) compatible programmer's DMA library                           |
  8. ;|  Version 2.0 by Christopher M. Box                                        |
  9. ;+---------------------------------------------------------------------------+
  10. ;|  Version 1.1 copyright (C) 1992, Heath I Hunnicutt                        |
  11. ;+---------------------------------------------------------------------------+
  12. ;|  Thanks to: Gary Nemirovsky, Heath I Hunnicutt                            |
  13. ;+---------------------------------------------------------------------------+
  14. ;|  This document is for free public distribution.  It is unlawful to        |
  15. ;|  sell this document, or any work based substantially upon it.             |
  16. ;+---------------------------------------------------------------------------+
  17. ;| PUBLIC DMA FUNCTIONS                                                      |
  18. ;| int dma_setup(int Channel,char far *Buffer,unsigned Length,int Dir)       |
  19. ;| int prevent_dma(int Channel)                                              |
  20. ;| int allow_dma(int Channel)                                                |
  21. ;| unsigned dma_count(int Channel)                                           |
  22. ;| unsigned dma_addr(int Channel)                                            |
  23. ;+---------------------------------------------------------------------------+
  24. ;| PUBLIC DATA                                                               |
  25. ;| int dma_errno                                                             |
  26. ;| char far *dma_errlist[]                                                   |
  27. ;+---------------------------------------------------------------------------+
  28. ;| HISTORY:                                                                  |
  29. ;|   Ver 1.0 - Initial Release                                               |
  30. ;|   Ver 1.1 - Error checking and reporting added to all functions           |
  31. ;|             dma_setup(..) should never crash your system now.             |
  32. ;|   Ver 1.2 - Changed mode to auto-initialise (Mod. by CMB)                 |
  33. ;|   Ver 2.0 - Major changes to deal with 2nd DMA controller (by CMB)        |
  34. ;+---------------------------------------------------------------------------+
  35.  
  36. Status          EQU     08h     ;DMAC status port (read)     \  same port
  37. Command         EQU     08h     ;DMAC command port (write)   /  (read/write)
  38. Request         EQU     09h     ;DMAC channel request (write-only)
  39. DMA_Mask        EQU     0Ah     ;DMAC DMA_Mask (write-only)
  40. Mode            EQU     0Bh     ;DMAC mode (write)
  41. byte_ptr        EQU     0Ch     ;byte pointer flip-flop
  42.  
  43. addr            EQU  000h  ; per-channel base address
  44. count           EQU  001h  ; per-channel byte count
  45.  
  46. IFDEF NON_AUTOINIT
  47. read_cmd        EQU     048h    ; read mode
  48. write_cmd       EQU     044h    ; write mode
  49. ELSE
  50. read_cmd        EQU     058h    ; autoinitialising read
  51. write_cmd       EQU     054h    ; auto write
  52. ENDIF
  53.  
  54. set_cmd         EQU     000h    ; DMA_Mask set (enable dma)
  55. reset_cmd       EQU     004h    ; DMA_Mask reset (disable)
  56.  
  57.                 DATASEG
  58. ; dma controller page register table
  59. ; this table maps from channel number to the i/o port number of the
  60. ; page register for that channel
  61.  
  62. page_table  DW  00087h  ; channel 0
  63.             DW  00083h  ; channel 1
  64.             DW  00081h  ; channel 2
  65.             DW  00082h  ; channel 3
  66.             DW  0ffffh  ; ch 4 (not used)
  67.             DW  0008Bh  ; ch 5
  68.             DW  00089h  ; ch 6
  69.             DW  0008Ah  ; ch 7
  70.  
  71. dmac2        DB 0    ; Flag set to non-zero when using the 2nd DMA controller
  72.  
  73. ; "Extra" messages are for future compatability with the Virtual DMA
  74. ; specification.
  75. DMA_E0          DB      0
  76. DMA_E1          DB      "Region not in contiguous memory.",0
  77. DMA_E2          DB      "Region crossed a physical alignment boundary.",0
  78. DMA_E3          DB      "Unable to lock pages.",0
  79. DMA_E4          DB      "No buffer available.",0
  80. DMA_E5          DB      "Region too large for buffer.",0
  81. DMA_E6          DB      "Buffer currently in use.",0
  82. DMA_E7          DB      "Invalid memory region.",0
  83. DMA_E8          DB      "Region was not locked.",0
  84. DMA_E9          DB      "Number of physical pages greater than table length.",0
  85. DMA_EA          DB      "Invalid buffer ID.",0
  86. DMA_EB          DB      "Copy out of buffer range.",0
  87. DMA_EC          DB      "Invalid DMA channel number.",0
  88. DMA_ED          DB      "Buffer not word-aligned.",0
  89. _dma_errlist DD DMA_E0, DMA_E1, DMA_E2, DMA_E3, DMA_E4, DMA_E5, DMA_E6, DMA_E7,\
  90.                 DMA_E8, DMA_E9, DMA_EA, DMA_EB, DMA_EC, DMA_ED
  91. _dma_errno   DW 0
  92.  
  93. ;char near *dma_errlist[]
  94. ;int dma_errno
  95. PUBLIC _dma_errlist,_dma_errno
  96.  
  97.                 CODESEG
  98. MACRO zero reg
  99.       xor reg,reg
  100. ENDM zero
  101.  
  102. MACRO adjust reg          ; Adjust register port for 2nd DMA cont
  103. local no_adjust
  104.       cmp [dmac2], 0
  105.       jz no_adjust
  106.       shl reg,1
  107.       add reg,0C0h
  108. no_adjust:
  109. ENDM adjust
  110.  
  111. PUBLIC _dma_setup,_prevent_dma,_allow_dma,_dma_count,_dma_addr
  112. ;+---------------------------------------------------------------------------+
  113. ;| int dma_setup(int Channel,char far *Buffer,unsigned Length,int Dir)       |
  114. ;| ------------------------------------------------------------------------- |
  115. ;| Channel = 0-7                                                             |
  116. ;| Buffer  = Address of data to transfer                                     |
  117. ;| Length  = Length of data to transfer                                      |
  118. ;| Dir     = Direction to move bytes.  1 == Out to the BUS (TO the card)     |
  119. ;|                                     0 == In from the BUS and cards.       |
  120. ;| ------------------------------------------------------------------------- |
  121. ;| Returns: 0 if no errors (dma_errno == 0)                                  |
  122. ;|         -1 if errors occurred (dma_errno set to indicate error.)          |
  123. ;+---------------------------------------------------------------------------+
  124. PROC _dma_setup
  125. ARG Channel:WORD,Buffer:DWORD,Len:WORD,Dir:WORD
  126.   push bp
  127.   mov  bp,sp
  128.         push bx cx dx si di
  129.   pushf
  130.  
  131.         mov  [_dma_errno],0
  132. ;Convert seg:ofs Buffer to 20-bit physical address
  133. ;Assumes operating in 8086/real-Mode
  134.         mov  bx,[WORD PTR Buffer]
  135.         mov  ax,[WORD PTR Buffer+2]
  136.         mov  cl,4
  137.         rol  ax,cl
  138.         mov  ch,al
  139.         and  al,0F0h
  140.         add  ax,bx
  141.         adc  ch,0
  142.         and  ch,0Fh
  143.         mov  di,ax
  144. ; (ch << 16) + di == The physical buffer base.
  145.  
  146. ; Check channel number range
  147.         mov  [dmac2],0
  148.         mov  bx,[Channel]
  149.         cmp  bx,7
  150.         jbe  @@Set_base
  151.         mov  [_dma_errno],0Ch
  152.         mov  ax,-1
  153.         jmp  @@ExitPt
  154. @@Set_base:
  155.         cmp  bx,4
  156.         jb   @@OkChannel
  157.         sub  bx,4
  158.         inc  [dmac2]
  159. @@OkChannel: ; BX contains the adjusted channel number
  160.  
  161. ;Determine which command byte will be written later
  162.         cmp  [WORD PTR Dir],0
  163.         jnz  SHORT @@Do_Read
  164.         mov  al,write_cmd
  165.         jmp  short @@Do_Mode
  166. @@Do_Read:
  167.         mov  al,read_cmd
  168. @@Do_Mode:
  169.         add  al,bl
  170.         zero ah
  171.         mov  si,ax
  172.         mov  ax,set_cmd    ;allow dma requests
  173.         add  al,bl
  174.         mov  cl,al
  175. ;si contains READ/WRITE command for DMA controller
  176. ;cl contains confirmation command for DMA controller
  177.         shl  bx,1
  178. ;bx == Port # Channel*2
  179.  
  180. ;-------------------------------------------------------------------------
  181. ; Calculations have been done ahead of time to minimize time with
  182. ; interrupts disabled.
  183. ;
  184. ; ch:di == physical base address (must be on word boundary for 16 bits)
  185. ;
  186. ; cl == Confirmation command    (Unmasks the channel)
  187. ;
  188. ; bx == I/O port Channel*2      (This is where the address is written)
  189. ;
  190. ; si == Mode command for DMA
  191. ;-------------------------------------------------------------------------
  192.         mov  ax,di              ;Let's check the address to see if we
  193.         add  ax,[Len]           ;span a page bo